#[[                                   目录结构

    >3rdlibs
      >cmakelib(cmake管理的库)
      >onlyHeaderlib   
        lib-files
        CMakeLists.txt--------------------------------------------(单头文件库)
      >onlyDllLib      
        importlib.cmake-------------------------------------------(导入已存在的库)
    CMakeLists.txt------------------------------------------------(管理第三方库)

    >mylib
      >include
        pch.hpp
      >src
      CMakeLists.txt----------------------------------------------(生成mylib)
      
    >main
      main.cpp
      CMakeLists.txt----------------------------------------------(使用 mylib)

    >test
      test.cpp
      CMakeList.txt-----------------------------------------------(测试 mylib)
    
    CMakeLists.txt------------------------------------------------(顶层cmake)
]]


#------------------------------------------------------------# CMakeLists.txt 顶层
cmake_minimum_required(VERSION 3.25)

project(use_cmake
    LANGUAGES CXX C
    DESCRIPTION "use cmake to manage project"
    VERSION 0.0.1
)

set(mylib_name "mylib")

add_subdirectory(3rdlibs)
add_subdirectory(mylib)
add_subdirectory(main)

#------------------------------------------------------------# 测试
option(ENABLE_TEST "Whether to enable testing" OFF)
# 自己始终启用测试 他人只会当作子目录
if(PROJECT_IS_TOP_LEVEL OR ENABLE_TEST) 
    include(CTest)
    enable_testing()
    add_subdirectory(test)
endif()

#------------------------------------------------------------# CMakeLists.txt 测试 
add_executable(test test.cpp)
add_test(NAME first_test COMMAND $<TARGET_FILE:test>)
target_link_libraries(test PRIVATE ${mylib_name})

# 解决[1]
target_precompile_headers(test REUSE_FROM ${mylib_name})


#------------------------------------------------------------# CMakeLists.txt 单头文件库
add_library(onlyHeaderlib INTERFACE)
target_include_directories(onlyHeaderlib INTERFACE <dirs>)


#------------------------------------------------------------# importlib.cmake 导入已存在的库(只有库文件)
set(LIB_PATH "" CACHE PATH "docs")
set(dll_file "${LIB_PATH}/bin/name.dll" CACHE INTERNAL "docs") # cmake-gui 不可见

add_library(<name> SHARED IMPORTED GLOBAL)

target_include_directories(<target> PUBLIC "${LIB_PATH}/include/...")
set_target_properties(<target>
    PROPERTIES
    IMPORTED_LOCATION "${LIB_PATH}/bin/name.dll"
    IMPORTED_IMPLIB "${LIB_PATH}/lib/name.lib"
)


#------------------------------------------------------------# CMakeLists.txt 管理第三方库的
add_subdirectory(cmakelib)
add_subdirectory(onlyHeaderlib)
include(onlyDllLib)


#------------------------------------------------------------# CMakeLists.txt 生成mylib
aux_source_directory(./src mylib_src)
file(GLOB_RECURSE mylib_headers ./include/*.hpp ./include/*.h)

add_library(${mylib_name} STATIC ${mylib_src} ${mylib_headers})
target_include_directories(${mylib_name} PUBLIC include)
target_compile_features(${mylib_name} PUBLIC cxx_std_17)
target_link_libraries(${mylib_name} PUBLIC cmakelib onlyHeaderlib onlyDllLib)

# [1]这里的 PUBLIC 会导致 依赖该目标的目标 也会编译头文件
target_precompile_headers(${mylib_name} PUBLIC ./include/pch.hpp)


#------------------------------------------------------------# CMakeLists.txt 使用mylib库
add_executable(main main.cpp)
target_link_libraries(main PRIVATE ${mylib_name})
target_precompile_headers(test REUSE_FROM ${mylib_name})

# 拷贝 dll
add_custom_command(TARGET main POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy_if_different ${dll_file} $<TARGET_FILE_DIR:main>
)
